#pragma once

#include "Interpreter.hpp"
#include "Lexer.hpp"
#include <cstddef>
#include <iostream>
#include <ostream>
#include <vector>

namespace std{
    template<class T>
    ostream&operator<<(ostream&os,const vector<T>&v){
        if(v.size()==0){
            os<<"[]";
            return os;
        }
        os<<"[";
        for(size_t i=0;i<v.size()-1;i++){
            os<<" "<<v[i]<<",";
        }
        os<<" "<<v[v.size()-1]<<"]";
        return os;
    }
}
namespace ztl {
    inline bool isDebug = false;
    template<class ...Ts>
    struct overloaded : Ts... {using Ts::operator()...;};
    template<class ...Ts>
    overloaded (Ts...) -> overloaded<Ts...>;

    void inline runCodeFromPath(std::string_view v){
    ztl::Lexer lexer = std::visit(ztl::overloaded{
        [](std::string &&s){
            return s;
        },
        [&v](const ztl::readFileToStrType::CannotOpenFile &){
            throw std::runtime_error(std::format("Cannot open file :{}",v));
            return std::string();
        }
    },ztl::readFileToStr(v));

    if(isDebug)std::cout<<"Lexer() return vector:\n"<<lexer.tokens<<'\n';;
    ztl::interpreter(lexer.tokens);
}
}